package com.ruoyi.spider;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.entity.ApiResponse;
import com.ruoyi.common.entity.BaiduUrlResource;
import com.ruoyi.common.entity.ResourceData;
import com.ruoyi.common.enums.SpiderKey;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.*;
import us.codecraft.webmagic.pipeline.ConsolePipeline;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.QueueScheduler;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 0617
 * @version 1.0
 * @description: 多级爬虫 - 先获取资源列表，再逐个请求详情
 */
@Slf4j
@Component
public class ProjectPageProcessor implements PageProcessor {


    private Site site = Site.me()
            .setRetryTimes(3)
            .setSleepTime(100)
            .setUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36")
            .addHeader("Referer", "https://xcx.you123.top/");

    private static final String LIST_URL_REGEX = "getResourceList\\?pageNum=\\d+";
    private static final String DETAIL_URL_REGEX = "getDetail\\?resourceId=\\d+&token=";

    @Override
    public void process(Page page) {
        String url = page.getUrl().toString();

        if (page.getUrl().regex(LIST_URL_REGEX).match()) {
            handleListPage(page);
        } else if (page.getUrl().regex(DETAIL_URL_REGEX).match()) {
            handleDetailPage(page);
        } else {
            log.warn("未知页面类型: {}", url);
            page.setSkip(true);
        }
    }



    /**
     * 处理资源列表页面（添加分页逻辑）
     */
    private void handleListPage(Page page) {
        String rawText = page.getRawText();
        log.info("✅ 列表页数据: {}", rawText);

        try {
            TypeReference<ApiResponse<List<ResourceData>>> typeRef = new TypeReference<ApiResponse<List<ResourceData>>>() {};
            ApiResponse<List<ResourceData>> response = JSONUtil.toBean(rawText, typeRef, false);

            if (response != null && "0".equals(response.getCode().toString())) {
                List<ResourceData> resourceList = response.getData();

                // 检查数据是否为空（停止条件）
                if (resourceList == null || resourceList.isEmpty()) {
                    log.info("📌 列表数据为空，停止爬取");
                    page.setSkip(true);
                    return;
                }

                // 处理当前页数据
                for (ResourceData resource : resourceList) {
                    String detailUrl = "https://xcx.you123.top/api/v1/wx70f12f240c3854b7/getDetail?resourceId="
                            + resource.getResourceId() + "&token=";
                    page.putField(SpiderKey.SPIDER_KEY_ResourceDatas.getKey(), resource);
                    page.addTargetRequest(detailUrl);
                }

                // 添加下一页请求
                int currentPage = extractPageNum(page.getUrl().toString());
                String nextPageUrl = generateNextPageUrl(page.getUrl().toString(), currentPage + 1);
                page.addTargetRequest(nextPageUrl);

                log.info("✅ 成功解析第{}页，发现{}个资源，已添加下一页", currentPage, resourceList.size());
            } else {
                log.warn("❌ 列表接口返回异常: code={}, msg={}", response.getCode(), response.getMsg());
            }
        } catch (Exception e) {
            log.error("❌ 解析列表页失败: {}", rawText, e);
        }
        page.setSkip(true);
    }

    /**
     * 从URL中提取当前页码
     */
    private int extractPageNum(String url) {
        try {
            String pageNumStr = url.substring(url.indexOf("pageNum=") + 8);
            return Integer.parseInt(pageNumStr);
        } catch (Exception e) {
            log.error("提取页码失败: {}", url, e);
            return 1;
        }
    }

    /**
     * 生成下一页URL
     */
    private String generateNextPageUrl(String currentUrl, int nextPage) {
        return currentUrl.replaceAll("pageNum=\\d+", "pageNum=" + nextPage);
    }
    /**
     * 处理资源详情页面
     */
    private void handleDetailPage(Page page) {
        String rawText = page.getRawText();
        log.info("✅ 详情页数据: {}", rawText);
        try {
            // 1. 先解析为通用Map结构
            TypeReference<ApiResponse<Map<String, Object>>> typeRef =
                    new TypeReference<ApiResponse<Map<String, Object>>>() {};
            ApiResponse<Map<String, Object>> response = JSONUtil.toBean(rawText, typeRef, false);

            if (ObjectUtil.isNotNull(response)
                    && "0".equals(response.getCode().toString())
                    && ObjectUtil.isNotNull(response.getData())) {

                // 2. 获取resource字段的JSON字符串
                Map<String, Object> data = response.getData();
                Object resourceObj = data.get("resource");

                if (resourceObj != null) {
                    // 3. 将嵌套对象单独转换为目标类型
                    BaiduUrlResource detail = JSONUtil.toBean(
                            // 转换为JSON字符串
                            JSONUtil.toJsonStr(resourceObj),
                            // 目标类型
                            BaiduUrlResource.class
                    );

                    /*String key = String.valueOf(detail.getResourceId());
                    result.put(key, detail);*/
                    page.putField(SpiderKey.SPIDER_KEY_DEATIL.getKey(), detail);

                    log.info("📌 已爬取详情: resourceId={}, title={}",
                            detail.getResourceId(), detail.getTitle());
                } else {
                    log.warn("❌ 详情页resource字段为空: {}", rawText);
                }
            } else {
                log.warn("❌ 详情页返回异常: code={}, msg={}",
                        response.getCode(), response.getMsg());
            }
        } catch (Exception e) {
            log.error("❌ 解析详情页失败: {}", rawText, e);
            page.setSkip(true);
        }
    }

    @Override
    public Site getSite() {
        return site;
    }

}